#include "optrzone.h"

#include <welcomedlg.h>
#include <QTimer>
#include "alertwindow.h"

#include <QTime>

#include "application.h"
#include "zonesmanager.h"

#include <optra/zoneinfo.h>
#include <optra/zoneinterface.h>

#include <optra/common/guiwindow.h>
#include <optra/common/logevent.h>
#include <optra/common/proxy.h>
#include <optra/common/db.h>

#include "zoneinstalui.h"
#include "applicationinstallui.h"
#include "eventview.h"


#include "shell.h"

extern Optra::Proxy *proxy;

OptraZone::OptraZone(Application* main, QObject *parent) :
        ZoneInterface(parent), main_(main)
{
    info_ = new Optra::ZoneInfo("optra", "optra base");
    WelcomeDlg* wd = new WelcomeDlg;
    info_->addView(new Optra::ZoneWindow("optra#welcome", "Welcome", wd));

    info_->addView(new Optra::ZoneWindow("optra#ApplicationInstall", "Application Managet", new ApplicationInstallUi));

    Optra::ZoneWindow *zmanager = new Optra::ZoneWindow("optra#zones", "Zones", new ZoneInstalUi);
    zmanager->setIcon(QIcon(":/icons/zonemanager"));
    info_->addTool(zmanager);

    info_->addTool(new Optra::ZoneWindow("optra#SystemInfo", "System Info", new Optra::GuiWindow(0, Op::html)));

    Optra::GuiWindow * about = new Optra::GuiWindow(0, Op::html);
    about->setUrl("about/about.html");
    Optra::ZoneWindow * aboutW= new Optra::ZoneWindow("optra#about", "About", about);
    aboutW->setIcon(QIcon(":icons/information"));
    info_->addView(aboutW);


    Optra::ZoneWindow * shell = new Optra::ZoneWindow("optra#script", "System Shell", new Shell);
    shell->setIcon(QIcon(":/icons/console"));
    info_->addTool(shell);


    eventView_ = new EventView;
    Optra::ZoneWindow* loggerView= new Optra::ZoneWindow("optra#events", "Events viewer", eventView_);
    loggerView->setIcon(QIcon(":/icons/log"));
    info_->addView(loggerView);

    updateState(Op::Ready);
}

void OptraZone::logEvent(Optra::LogEvent* ev)
{
    eventView_->addEvent(ev);
}

bool OptraZone::event(QEvent *event)
{
    if (event->type() == (QEvent::Type)Optra::LogEvent::thetype){
        Optra::LogEvent* le = static_cast<Optra::LogEvent*>(event);
        logEvent(le);
        return true;
    }
    return QObject::event(event);
}

OptraZone::~OptraZone()
{
    delete info_;
}

bool OptraZone::install()
{
    // info("Creating Optra Config Database");
    QSqlQuery query = db()->query();
    if (!db()->db().tables().contains("zones")){
        if (!query.exec("CREATE TABLE zones (id INTEGER PRIMARY KEY AUTOINCREMENT , "
                        "path VARCHAR(20), displayname VARCHAR(50), guid VARCHAR(38), uni VARCHAR(20))")){
            qDebug() << query.lastError().text();
        }
    }

    if (!db()->db().tables().contains("applications")){
        if (!query.exec("CREATE TABLE applications (id INTEGER PRIMARY KEY AUTOINCREMENT , "
                        "path VARCHAR(20), guid VARCHAR(38), displayname VARCHAR(50), uni VARCHAR(20), typeid INTEGER)")){
             qDebug() << query.lastError().text();
        }
    }

    if (!db()->db().tables().contains("applicationtype")){
        query.exec("CREATE TABLE applicationstype (id INTEGER PRIMARY KEY AUTOINCREMENT , "
                   "name VARCHAR(20))");
        query.exec("INSERT INTO applicationstype (name) VALUES('Optra')");
        query.exec("INSERT INTO applicationstype (name) VALUES('Script')");
        query.exec("INSERT INTO applicationstype (name) VALUES('Native')");
    }

    if (!db()->db().tables().contains("applicationsdep")){
        query.exec("CREATE TABLE applicationsdep (id INTEGER PRIMARY KEY AUTOINCREMENT , "
                   "sid INTEGER, tid INTEGER, typeid INTEGER, tunique VARCHAR(20))");

    }

    if (!db()->db().tables().contains("plugins")){
        query.exec("CREATE TABLE plugins (id INTEGER PRIMARY KEY AUTOINCREMENT , "
                   "path VARCHAR(20), guid VARCHAR(38), displayname VARCHAR(50), zoneid INTEGER)");
    }

    if (!db()->db().tables().contains("dependency")){
        query.exec("CREATE TABLE dependency (id INTEGER PRIMARY KEY AUTOINCREMENT , "
                   "sid INTEGER, tid INTEGER, typeid INTEGER, tunique VARCHAR(20))");
    }

    if (!db()->db().tables().contains("dependencytype")){
        query.exec("CREATE TABLE dependencytype (id INTEGER PRIMARY KEY AUTOINCREMENT , "
                   "displayname VARCHAR(50), shortname VARCHAR(3))");

        query.exec("INSERT INTO dependencytype (displayname, shortname) VALUES('Required', 'req')");
        query.exec("INSERT INTO dependencytype (displayname, shortname) VALUES('Function', 'fun')");
        query.exec("INSERT INTO dependencytype (displayname, shortname) VALUES('Future', 'fut')");
    }


    if (!db()->db().tables().contains("zoneviews")){
        query.exec("CREATE TABLE zoneviews (id INTEGER PRIMARY KEY AUTOINCREMENT , "
                   "sid INTEGER, zid INTEGER)");
    }


    return true;

}

bool OptraZone::configure(bool read)
{
    debug("Optra Config");


    //debug("Optra Config");

    return true;
}

QString OptraZone::version()const
{
    return O_SDK_VERSION_STR;
}

void OptraZone::go()
{
    emit ready();
}

void OptraZone::zloaded(const QString& name)
{
    emit zoneLoaded(name);
}

QStringList OptraZone::availableZones()const
{
    return main_->zones()->zoneProcess().keys();
}

AlertWindow* OptraZone::showTimedInformationWindow(QString message, int time)
{
    static  AlertWindow* dlg = NULL;
//    if (dlg != NULL){
//        delete dlg;
//    }
    dlg = new AlertWindow(NULL, message, time);
    return dlg;
}


void OptraZone::activateView(const QString& id)
{
    main_->menuClicked(id);
}

Optra::GuiWindow* OptraZone::htmlWindow(int width, int height)
{
    Optra::GuiWindow * win = new Optra::GuiWindow(0, Op::html);
    win->resize(width, height);
    return win;
}
